Forum des exercices du projet Zuul

Exercice 7.46

  
 
Avatar Denis BUREAU
Exercice 7.46
par Denis BUREAU, samedi 6 mars 2021, 21:04
 

Add a transporter room. Whenever the player enters leaves this room, he/she is randomly transported into one of the other rooms.
Note: Coming up with a good design for this task is not trivial. It might be interesting to discuss design alternatives for this with other
students. (We discuss design alternatives for this task at the end of Chapter 9. You should read it carefully.)

1) Tenir compte de la lecture du chapitre 9.11 (en particulier getExit() et les classes TransporterRoom et RoomRandomizer).

2) L'exercice 18.5, marqué optionnel jusqu'ici, devient obligatoire préalablement à cet exercice ; mais vous n'êtes pas obligé de donner accès à 100% des Rooms à partir de la TransporterRoom.

Contrainte : Utiliser la classe Random ainsi que la bonne méthode nextInt.

Aide : Dans le cas d'un tableau ou d'une ArrayList, il suffit de mettre les Room concernées au début, et de dire combien de Room il faut prendre en compte. Dans le cas d'une HashMap, il vous faudra trouver une autre astuce.

Ne pas oublier de lire les échanges ci-dessous pour mieux comprendre la bonne manière de réaliser cet exercice.

Avatar Jonathan MORELL
Re: Exercice 7.46
par Jonathan MORELL, lundi 19 mai 2014, 20:27
 

Après avoir fini cette exercice, je pense ne pas l'avoir traité comme il faut. J'ai vu que vous demandé d'expliquer la classe Random, nextInt et seed.
Je ne l'ai cependant pas utilisé et j'ai créé ma méthode à partir de Math.random()*100%(vNombreDeRoom).
Somme-nous obligé de créer un objet Random pour créer notre méthode ?

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, lundi 19 mai 2014, 23:46
 

Oui, vous devez apprendre à vous servir de la classe Random.

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, vendredi 30 mai 2014, 14:19
 

Un étudiant a écrit :

.../...
De toute façon, je me retrouve confronté au même problème dans le TransporterRoom? Car, à moins que je ne crée un attribut de type Room[] dans mon gameEngine où j'ai créé mes variables Room par exemple vJardin, vDonjon etc, je ne pourrai pas créer de méthode retournant ce tableau, qui pourra être appelée par la classe TransporterRoom lors d'un changement de Room (goRoom()) ?

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, vendredi 30 mai 2014, 14:21
 

Pourquoi semblez-vous vous interdire de créer "un attribut de type Room[] dans mon gameEngine où j'ai créé mes variables Room" ?
Lisez l'exercice 7.18.5.

Ensuite, vous pourriez passer ce tableau ou cette liste de Room à la TransporterRoom lors de sa création ...

Avatar William AFONSO
Re: Exercice 7.46
par William AFONSO, vendredi 30 mai 2014, 17:32
 

Merci, ca marche à présent. Mais je n'arrive pas encore à synthétiser de nombre aléatoire. Voici ce que je fais:

import java.util.Random;

public int getRandomNumber(){

return nextInt(7);
       }
  

Le compilateur le dit qu'il ne trouve pas la méthode nextInt() ou nextInt(int). Dois-je appeler nextInt(7) sur quelque chose?

 

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, vendredi 30 mai 2014, 18:22
 

Bien sûr, comme pour toute méthode !

Si c'est une méthode statique, on écrit Classe.methode(); sinon on écrit objet.methode();

Dans le premier cas, methode doit appartenir à Classe, dans le deuxième cas, elle doit appartenir à la classe de objet.

(s'il vous arrive d'écrire juste methode(); c'est que vous ne suivez pas les directives qui vous ont été données, à savoir écrire this.methode();)

Avatar Yi Heng CAO
Re: Exercice 7.46
par Yi Heng CAO, lundi 27 avril 2015, 15:26
 

Bonjour,

Pour vérifier d'abord si j'ai bien compris ce qu'il faut faire dans l'exercice :
Le but est de faire en sorte que le joueur, lorsqu'il quitte une Transporter Room, se retrouve dans une autre salle aléatoirement.

Pour ça, il faut créer une classe TransporterRoom qui est une sorte de Room et y ajouter les méthodes qui sont dans le chapitre 9.11.
Il faut aussi créer une autre classe RoomRandomizer avec la méthode findRandomRoom().

Avec les questions posées précédemment, il faut importer la classe Random, utiliser la méthode nextInt(), et utiliser seed.

Ce que je ne comprends pas, c'est comment y parvenir à cause de différent point...

1. Je ne vois pas si la classe RoomRandomizer est une sorte de Room ou TransporterRoom.
2.
Pour les attributs des deux nouvelles classes, je ne vois pas du tout quoi mettre.
3. La méthode nextInt() retourne un int mais je ne vois pas comment je pourrais m'en servir, parce que pour l'exercice 18.5, j'ai fait une HashMap et non un tableau... Donc faut-il plutôt faire un tableau ?

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, lundi 27 avril 2015, 17:18
 

Vous avez bien compris.

1. Aucune des deux !  La TransporterRoom a juste besoin d'un objet RoomRandomizer pour fonctionner, ce qui répond aussi à votre question 2 pour TransporterRoom.

2. RoomRandomizer a besoin d'un tableau ou d'une liste de Room pour fonctionner, même si on peut passer une HashMap à son constructeur (voir votre question 3).

3. Le plus simple est effectivement de prévoir un tableau à l'exercice 7.18.5, mais vous pouvez aussi extraire une ArrayList de la HashMap grâce à sa méthode values() et au constructeur ArrayList(Collection).

Avatar Yi Heng CAO
Re: Exercice 7.46
par Yi Heng CAO, lundi 30 décembre 2019, 19:24
 

Merci de votre réponse, cela m'a permis d'avancer. Malgré cela je rencontre d'autre difficulté.
J'essaye donc actuellement de répondre à cet exercice en gardant la HashMap au lieu d'un tableau comme vous avez dit que c'était possible.

En regardant la Javadoc de la méthode values(), je comprends qu'elle permet de retourner une Collection avec les valeurs de la HashMap, donc en l'occurrence, une Collection de Room.
Quant au constructeur de l'ArrayList(Collection), celui-ci demande une Collection en paramètre.
Donc pour récupérer une Room de l'ArrayList, j'utilise la méthode get() qui demande un int correspondant à l'index.


J'en ai donc déduit mon code suivant :

         ... code supprimé pour ne pas influencer les futurs lecteurs ...

Sauf qu'il m'indique l'erreur " incompatible type " au niveau du return.

De plus, je ne comprends pas ce qu'est un seed et donc comment m'en servir...

Merci d'avance

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, mardi 28 avril 2015, 10:54
 

Essayez de remplacer votre instruction return par return null;
Maintenant, ça compile, mais vous obtenez un warning vous avertissant que vous utilisez des opérations non vérifiées donc non sûres.
Cela provient de votre déclaration de vList : c'est une liste de quoi ???

Après avoir effectué la correction nécessaire, vous pouvez remettre votre instruction return et ça devrait compiler sans erreur ni warning.

Par contre, il faudrait améliorer votre calcul de vRandomNumber : que se passerait-il si, dans GameEngine, vous décidiez de retirer une pièce de la HashMap des Room ?

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, mardi 28 avril 2015, 10:56
 

Pour comprendre l'utilité de la seed, veuillez lire le petit extrait de livre donné dans A SAVOIR EXPLIQUER juste après l'exercice 7.46.
Si vous ne comprenez pas quelque chose, demandez.

Avatar Yi Heng CAO
Re: Exercice 7.46
par Yi Heng CAO, mardi 28 avril 2015, 12:06
 

Merci encore de vos réponses, cela m'a permis comprendre où était mes erreurs.

Pour ma variable vList, j'ai oublié de préciser qu'il s'agissait d'une liste de Room lors de sa déclaration.
En ce qui concerne le calcul de vRandomNumber, si je rajoute des salles dans ma classe GameEngine, les nouvelles salles ne seraient pas prise en compte et donc le nombre de salle serait faussé. Pour éviter cela, il est préférable de regarder la taille de la collection.

Pour le seed, si je ne me trompe pas, il s'agit d'un algorithme qui permet de fournir des chiffres "pseudo-aléatoire", c'est-à-dire qu'en choisissant un seed, les chiffres obtenus par cet algorithme seront toujours les mêmes.
Mais comment doit on le choisir ? En prenant un chiffre en particulier, lorsque je sors de ma salle, je me retrouve toujours dans la même salle.

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, mardi 28 avril 2015, 14:02
 

Vous avez effectivement bien compris ce qu'il fallait corriger.

Pour votre dernière question, en fonctionnement normal, on ne veut pas avoir toujours la même suite de nombres aléatoires : il ne faut donc pas fournir une seed ! (dans ce cas, la JVM utilise le nombre de millisecondes écoulées depuis le démarrage de l'ordinateur ce qui garantit à peu près un nombre "aléatoire")

Fournir une seed peut être utile en mode debug lorsque vous voulez reproduire un comportement problématique.

Avatar Dorian TONA
Re: Exercice 7.46
par Dorian TONA, mercredi 27 mai 2015, 11:53
 

Bonjour,

Est-il obligatoire de créer la classe RoomRandomizer pour cet exercice ? J'ai réalisé l'exercice en écrivant le code qu'il faut visiblement mettre dans la classe RoomRandomizer (en utilisant Random, prendre une  dans le getExit de TransporterRoom. Dans la mesure où ça marche parfaitement avec "moins" de code, je n'arrive pas à cerner l'utilité d'ajouter une telle classe (elle possède sûrement des avantages que je n'ai pas remarqué mais pour l'instant je sèche).

Avatar Dorian TONA
Re: Exercice 7.46
par Dorian TONA, mercredi 27 mai 2015, 16:53
 

Correction (ça voulait pas dire grand chose sinon ^^') :

en écrivant le code qu'il faut visiblement mettre dans la classe RoomRandomizer (en utilisant Random, prendre une Room parmis celles disponibles au hasard) dans le getExit de TransporterRoom.*
Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, lundi 8 juin 2015, 11:33
 

Suite à un pb technique, je viens seulement d'être prévenu de votre message.

Oui, il faut suivre les recommandations du chapitre 9.11 que vous avez lu, et qui vous explique pourquoi cette structuration en plusieurs classes ayant chacune leur rôle bien défini est préférable.

Avatar Enzo MARIONI
Re: Exercice 7.46
par Enzo MARIONI, samedi 30 mai 2015, 17:03
 

Bonjour monsieur, 

Est-il vraiment nécessaire de créer la classe Transporter Room ? car d'après mon code j'en ai nullement besoin. La majorité de mes Rooms étant de bases des transporter rooms (ajout d'une variable pour définir si oui ou non elle le sont).

Merci d'avance.

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, lundi 8 juin 2015, 11:39
 

Suite à un pb technique, je viens seulement d'être prévenu de votre message.

Oui, elle est indispensable, comme expliqué au chapitre 9.11 que vous avez dû lire.
L'objectif de cet exercice n'est pas d'ajouter une pièce qui vous téléporte je ne sais où, mais de comprendre comment l'utilisation de l'héritage et du polymorphisme vous permet ici d'ajouter cette possibilité sans toucher au code existant, alors que vous avez dû modifier bcp de choses dans le GameEngine et/ou le Player ...

Avatar Joachim MOSNINO
Re: Exercice 7.46
par Joachim MOSNINO, mardi 2 juin 2015, 13:22
 
Bonjour Monsieur,


Ma classe TransporterRoom est codé, simplement une fois que j'ai effectué le test dans la méthode goRoom() pour savoir si ma Room est ou non une TransporterRoom, je ne vois pas comment spécifier qu'il faut utiliser le getExit() de la sous-classe TransporterRoom et non le getExit() normal de la classe Room...

Merci de votre aide,

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, lundi 8 juin 2015, 11:42
 

Suite à un pb technique, je viens seulement d'être prévenu de votre message.

Relisez le chapitre 9.11. Il n'y a besoin d'aucun test pour savoir si c'est une TransporterRoom. L'utilisation de la bonne version de getExit() est automatique grâce au polymorphisme.
Revoyez également votre cours sur l'héritage, la redéfinition, et les types déclaré et constaté.

Avatar Johan POGNON
Re: Exercice 7.46
par Johan POGNON, samedi 26 novembre 2016, 13:41
 
Je ne vois pas bien ce qu'il faut faire exactement. Afin de générer une randomRoom, il faut déjà avoir connaissance de toutes les rooms existantes. Pour cela, je ne sais pas vraiment comment faire.
Faudrait-il modifier la classe GameEngine et créer un tableau de Room qui sera un nouvel attribut, puis à chaque création de Room, nous l'affectons à un indice du tableau?

Puis nous pouvons alors donner en paramètre le tableau de Room à getExits() (dans la classe TransporterRoom) qui va à son tour donner à la classe RoomRandomizer pour utiliser findRandomRoom?
Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, dimanche 27 novembre 2016, 18:10
 

> Afin de générer une randomRoom, il faut déjà avoir connaissance de toutes les rooms existantes
>

Relisez l'exercice 7.18.5 : vous pouvez choisir les Room parmi lesquelles vous tirerez au sort.

> créer un tableau de Room qui sera un nouvel attribut, puis à chaque création de Room, nous l'affectons à un indice du tableau?
>

Cela impliquerait de connaître le nombre de pièces et de changer la taille du tableau à chaque ajout/suppression de pièce.
Mais une ArrayList semble appropriée ...

> donner en paramètre le tableau de Room à getExits() (dans la classe TransporterRoom)
>

Surtout pas ! Il ne faut pas toucher à la signature de getExit (et non getExits) ; relisez le chapitre 9.11

> donner à la classe RoomRandomizer pour utiliser findRandomRoom
>

C'est l'objet de type TransporterRoom qui fera cela.

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, vendredi 9 décembre 2016, 14:57
 

Un étudiant a écrit :

Bonjour,

dans cet exercice lorsque l'on sort de la room aléatoire doit on effacer l'historique des salles parcourus ou bien doit on pouvoir revenir avec le back ?


Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, vendredi 9 décembre 2016, 14:59
 

Les deux solutions sont acceptables, cela dépend un peu de la signification que vous attribuez à back dans votre jeu.

Signalez la solution retenue dans le rapport.

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, mercredi 16 décembre 2020, 15:09
 

Un étudiant a écrit :

J'ai une question à propos de l'exercice 7.46, j'ai créé mes deux classe TransporterRoom et RoomRandomizer et je voulais savoir si je peux mettre la méthode findRandomRoom() en static étant donné que ma classe RoomRandomizer n'a pas d'attribut et je ne vois pas l'utilité de créer un objet de ce type dans TransporterRoom.
Je peux tout simplement appeler le RoomRandomizer.findRandomRoom() non?
Et je ne pourrais d'ailleurs pas faire pareil pour la hashmap de room qui se trouve dans game engine?


Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, mercredi 16 décembre 2020, 15:20
 
  1. Si vous créez plusieurs TransporterRoom, vous pourriez conserver la possibilité d'utiliser des RoomRandomizer différents.
    Le rendre static dénote une conception plus fermée, mais ce ne sera pas compté comme faux.

  2. Il est effectivement peu probable que vous ayez plus d'un GameEngine, donc pourquoi pas.
    Mais la cohérence voudrait alors que tout soit static dans cette classe ; beaucoup de modifications en perspective ...
Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, lundi 4 janvier 2021, 18:54
 

Un étudiant a écrit :

J'aimerais être sûr d'avoir bien compris ce qui est demandé pour l'exercice de la transporter Room :
est-ce comme la trap door il faut spécifier la transporter Room dans la procédure createRooms() de la classe GameEngine?
Dans ce cas, faut- il également supprimer toutes les sorties qui lui sont associées? 


Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, lundi 4 janvier 2021, 19:00
 

1) La TransporterRoom doit être créée dans createRooms, comme toutes les autres Rooms ...

2) Par contre, il est inutile de supprimer toutes les sorties, cela donne un choix apparent au joueur, et augmente sa surprise.

Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, vendredi 30 avril 2021, 15:39
 

Un étudiant a écrit :

... si le joueur décide de sortir de la transporter room en tapant une commande du style "aller Sud", il est transporté.
Et s'il décide de faire retour dans cette nouvelle pièce, je lui empêche de le faire.

Ma question était : si le joueur rentre dans la transporter Room, et qu'il rentre "retour" au lieu d'une direction, doit il revenir dans la pièce avant la transporter Room ou faut-il le transporter aléatoirement ?


Avatar Denis BUREAU
Re: Exercice 7.46
par Denis BUREAU, vendredi 30 avril 2021, 15:42
 

Les deux solutions sont acceptables, cela dépend un peu de la signification que vous attribuez à back dans votre jeu, et à votre volonté de piéger ou non le joueur ...

Signalez la solution retenue dans le rapport.